package org.jeecg.modules.api.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.aspect.annotation.EntityDict;
import org.jeecg.common.constant.AIConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.MD5Util;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.third.aipocr.AipFaceService;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.third.sendsms.util.HttpClientUtil;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.model.SysLoginModel;
import org.jeecg.modules.system.service.ISysDictService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.wlhy.company.entity.HyCompany;
import org.jeecg.modules.wlhy.company.service.IHyCompanyService;
import org.jeecg.modules.wlhy.customer.entity.HyCustomer;
import org.jeecg.modules.wlhy.customer.entity.HyCustomerCompany;
import org.jeecg.modules.wlhy.customer.service.IHyCustomerCompanyService;
import org.jeecg.modules.wlhy.utils.UserUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @Author scott
 * @since 2018-12-17
 */
@RestController
@RequestMapping("/api/wlhy")
@Api(tags="用户登录")
@Slf4j
public class ApiLoginController {

	@Value(value="${customer.roleid}")
	private String customerRoleID;

	@Autowired
	private ISysUserService sysUserService;

	@Autowired
	private RedisUtil redisUtil;

	@Resource
	private BaseCommonService baseCommonService;

	@Autowired
	private ISysDictService sysDictService;

	@Autowired
	private AipFaceService aipFaceService;

	@Autowired
	private UserUtil userUtil;

	@Autowired
	private IHyCompanyService hyCompanyService;

	@Autowired
	private IHyCustomerCompanyService hyCustomerCompanyService;

//	private static final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";

	//设置登陆次数超过5次，锁定10分钟
	private boolean isDidableLogin(String username){
		String loginkey = "loginfail:"+username;
		//检查是否超过5次
		if(redisUtil.hasKey(loginkey)){
			int loginNum = (int) redisUtil.get(loginkey);
			if(loginNum >= 5){
				return true;
			}
		}
		return false;
	}

	//设置登陆次数超过5次，锁定10分钟
	private void addLoginNum(String username){
		String loginkey = "loginfail:"+username;
		if(!redisUtil.hasKey(loginkey)){
			redisUtil.set(loginkey, 1, 10*60);
		}else {
			int loginNum = (int) redisUtil.get(loginkey);
			loginNum = loginNum+1;
			redisUtil.set(loginkey, loginNum, 10*60);
		}
	}

	@ApiOperation(value="获取公司列表", notes="获取公司列表")
	@GetMapping(value = "/getCompanyList")
	public Result<?> getCompanyList() {
		List<HyCompany> list = hyCompanyService.list(new QueryWrapper<HyCompany>().eq("iz_used", "1"));
		List<Map> list2 = new ArrayList<>();
		for (HyCompany hyCompany : list) {
			Map<String,String> map = new HashMap<>();
			map.put("id",hyCompany.getId());
			map.put("companyName",hyCompany.getCompanyName());
			list2.add(map);
		}
		return Result.OK(list2);
	}
	/**
	 * APP货主管理-货主注册
	 * @param sysLoginModel
	 * @return
	 */
	@AutoLog(value = "APP货主管理-货主注册")
	@ApiOperation(value="APP货主管理-货主注册", notes="APP货主管理-货主注册")
	@PostMapping(value = "/customer/register")
	@EntityDict
	public Result <?> register(@RequestBody SysLoginModel sysLoginModel, HttpServletResponse response) {
		Result<JSONObject> result = new Result<>();
		String phone = sysLoginModel.getPhone();
		String smscode = sysLoginModel.getSmscode();
		Object code = redisUtil.get(phone);

		SysUser sysUser2 = sysUserService.getUserByPhone(phone);
		if (sysUser2 != null) {
			result.setMessage("该手机号已注册");
			result.setSuccess(false);
			return result;
		}
		if (!smscode.equals(code)) {
			result.setMessage("手机验证码错误");
			result.setSuccess(false);
			return result;
		}
		if(StringUtils.isEmpty(sysLoginModel.getPassword())){
			result.setMessage("密码不能为空！");
			result.setSuccess(false);
			return result;
		}

		//添加登陆账号
		SysUser user = new SysUser();
//		String username = phone;//设置登陆账号为手机号
		String username = sysUserService.createRandomUserName();//随机生成账号
		user.setUType("2");
		user.setUsername(username);
		user.setRealname(phone);
		user.setPhone(phone);
		user.setCreateBy(phone);
		user.setCreateTime(new Date());//设置创建时间
		String salt = oConvertUtils.randomGen(8);
		user.setSalt(salt);
		user.setPassword(sysLoginModel.getPassword());//设置默认密码123456
		String passwordEncode = PasswordUtil.encrypt(user.getUsername(), user.getPassword(), salt);
		user.setPassword(passwordEncode);
		user.setStatus(1);
		user.setClientId(sysLoginModel.getClientId());
		user.setDelFlag(CommonConstant.DEL_FLAG_0);
		//sysUserService.save(user);
		sysUserService.addUserWithRole(user, customerRoleID);
		SysUser sysUser  = sysUserService.getUserByPhone(phone);
		//添加日志
		baseCommonService.addLog("货主注册: " +phone + ",注册成功！",
				CommonConstant.LOG_TYPE_1, null);
		setUserInfo(sysUser, result, response);
		return result;
	}

	@ApiOperation("货主App登录接口")
	@AutoLog(value = "APP货主管理-登录接口")
	@RequestMapping(value = "/customer/login", method = RequestMethod.POST)
	public Result<JSONObject> customerLogin(@RequestBody SysLoginModel sysLoginModel, HttpServletResponse response){
		Result<JSONObject> result = new Result<JSONObject>();
		String phone = sysLoginModel.getUsername();
		if(StringUtils.isEmpty(phone)){
			result.error500("用户名不能为空");
			return result;
		}

		if(isDidableLogin(phone)){
			result.error500("连续登陆失败5次，账户锁定10分钟！");
			return result;
		}
		String password = sysLoginModel.getPassword();
		if(StringUtils.isEmpty(password)){
			result.error500("密码不能为空");
			return result;
		}

		SysUser sysUser = sysUserService.getUserByPhone(phone);
		result = sysUserService.checkUserIsEffective(sysUser);
		if(!result.isSuccess()) {
			addLoginNum(phone);
			return result;
		}

		if(!"3".equals(sysUser.getUType()) && !"2".equals(sysUser.getUType())){
			addLoginNum(phone);
			result.error500("不是货主账号,不能登录");
			return result;
		}

		//2. 校验用户名或密码是否正确
		String username = sysUser.getUsername();
		String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
		String syspassword = sysUser.getPassword();
		if (!syspassword.equals(userpassword)) {
			addLoginNum(phone);
			result.error500("用户名或密码错误");
			return result;
		}
		if( StringUtils.isNotEmpty(sysLoginModel.getClientId())){
			sysUser.setClientId(sysLoginModel.getClientId());
			sysUserService.updateById(sysUser);
		}

		setUserInfo(sysUser, result, response);
		return result;
	}

	private  void setUserInfo( SysUser sysUser, Result<JSONObject> result, HttpServletResponse response){

		// 获取用户部门信息
		JSONObject obj = new JSONObject();
		result.setResult(obj);


		//用户信息
		String syspassword = sysUser.getPassword();
		String username = sysUser.getUsername();

		// 生成token
		String token = JwtUtil.sign(username, syspassword);

		HyCustomer customer = userUtil.CheckUserRole(sysUser , result);
		if(customer!=null){
			//检查选择的公司是否签合同
			HyCustomerCompany customerCompany = hyCustomerCompanyService.getByCustomerId(customer.getId());
			if(customerCompany ==null){
				throw new JeecgBootException("未找到货主签约信息");
			}
//			HyCompany company = hyCompanyService.getById(customerCompany.getCompanyId());
//			if(company ==null){
//				throw new JeecgBootException("公司信息不存在");
//			}

		}

		// 设置token缓存有效时间
		redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
//		redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000);
		redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, 60*60*12);



		LoginUser loginUser = new LoginUser();
		BeanUtils.copyProperties(sysUser, loginUser);

		obj.put("token", token);
		obj.put("userInfo", loginUser);
		obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
		obj.put("customer", customer);
		obj.put("customerExamineStatus", customer !=null ? customer.getExamineStatus() : "0");
		result.setResult(obj);
		result.success("登录成功");

		sysUserService.setUserCookie(sysUser.getUsername(), response);
		//添加日志
		baseCommonService.addLog("货主: " + sysUser.getUsername() + ",登录成功！", CommonConstant.LOG_TYPE_1, null, loginUser);
	}

	/**
	 * 手机号登录接口
	 *
	 * @param jsonObject
	 * @return
	 */
	@ApiOperation("货主App手机登录接口")
	@PostMapping("/customer/phoneLogin")
	@AutoLog(value = "货主App手机登录接口")
	public Result<JSONObject> customerPhoneLogin(@RequestBody JSONObject jsonObject, HttpServletResponse response) {
		Result<JSONObject> result = new Result<JSONObject>();
		String phone = jsonObject.getString("mobile");
		if(StringUtils.isEmpty(phone)){
			result.error500("手机号不能为空");
			return result;
		}
		if(isDidableLogin(phone)){
			result.error500("连续登陆失败5次，账户锁定10分钟！");
			return result;
		}

		String smscode = jsonObject.getString("captcha");
		if(StringUtils.isEmpty(smscode)){
			result.error500("手机验证码不能为空");
			return result;
		}
		Object code = redisUtil.get(phone);
		if (!smscode.equals(code)) {
			addLoginNum(phone);
			result.setMessage("手机验证码错误");
			return result;
		}

		String clientId = jsonObject.containsKey("clientId")  ? jsonObject.getString("clientId") : StringUtils.EMPTY;

		//校验用户有效性
		SysUser sysUser = sysUserService.getUserByPhone(phone);
		result = sysUserService.checkUserIsEffective(sysUser);
		if(!result.isSuccess()) {
			return result;
		}

		if(!"3".equals(sysUser.getUType()) && !"2".equals(sysUser.getUType())){
			addLoginNum(phone);
			result.error500("不是货主账号,不能登录");
			return result;
		}

		if(StringUtils.isNotEmpty(clientId)){
			sysUser.setClientId(clientId);
			sysUserService.updateById(sysUser);
		}

		setUserInfo(sysUser, result, response);

		return result;
	}


	@ApiOperation(value="APP货主管理-百度人脸对比", notes="APP货主管理-百度人脸对比")
	@PostMapping("/customer/face/matchFace")
	@ResponseBody
	public Result<?>  matchFace(@RequestBody JSONObject  object , HttpServletRequest req) {

		String imageBase64No1  = object.get("imageBase64No1").toString();
		String imageBase64No2  = object.get("imageBase64No2").toString();
		if(StringUtils.isEmpty(imageBase64No1) || StringUtils.isEmpty(imageBase64No2)) {
			return Result.error("你的人脸对比参数不完整!");
		}

		String resourcesString = aipFaceService.matchFace(imageBase64No1, imageBase64No2);
		if(StringUtils.isEmpty(resourcesString)){
			return Result.error("人脸对比失败!");
		}
		JSONObject jsonObject = JSONObject.parseObject(resourcesString);
		JSONObject resultJsonObject = jsonObject.getJSONObject("result");
		if(resultJsonObject == null){
			return Result.error("人脸对比失败,不是同一个人!") ;
		}
		if(resultJsonObject.get("score") != null ){
			int score = resultJsonObject.getIntValue("score");
			return  score > AIConstant.AI_FACE_COMPARE_SCORE ?
					Result.OK() :
					Result.error("人脸对比失败,不是同一个人!") ;
		}
		if(resultJsonObject.get("error_code") != null){
			return Result.error(resultJsonObject.get("error_msg").toString());
		}
		return Result.error("人脸对比失败!");
	}


//	private void setUserCookie(String username, HttpServletResponse response) {
//		Cookie cookie= new Cookie(CommonConstant.X_PC_COOKIE, MD5Util.MD5Encode(username, "utf-8"));
//		cookie.setPath("/");
//		cookie.setMaxAge(60 * 60 * 24 * 30);
//		((HttpServletResponse)response).addCookie(cookie);
//		log.info("APP货主登录设置cookie - CMAP_SECKEY - {}", cookie.getValue());
//
//		return;
//	}

	@GetMapping(value = "/getwxcode")
	public Result<?> getwxcode(@RequestParam(name="appid") String appid,
								   @RequestParam(name="secret") String secret,
								   @RequestParam(name="js_code") String js_code,
								   HttpServletRequest req) {
//		if(StringUtils.isEmpty(appid)) {
//			return Result.error("appid不能为空");
//		}
//		if(StringUtils.isEmpty(secret)) {
//			return Result.error("secret不能为空");
//		}
//		if(StringUtils.isEmpty(js_code)) {
//			return Result.error("js_code不能为空");
//		}
		String url = "https://api.weixin.qq.com/sns/jscode2session?appid="+appid+"&secret="+secret+"&js_code=" + js_code;
		String ret = HttpClientUtil.doGet(url);
		return Result.OK(ret);
	}
}
